8  If条件语句 制作交易条件单

8.1 引言条件判断在金融决策中的重要性

条件判断是程序设计中最基本也是最重要的控制结构之一。在金融交易和风险管理中,几乎所有的决策都基于条件判断:价格是否达到目标位?风险是否超过阈值?市场状态是否符合交易策略?

8.2 本章学习目标

通过本章学习,你将能够:

  1. 写出 if/elif/else 的语法结构,说明分支的求值顺序与缩进在 Python 中的作用
  2. 使用比较运算符与 andornot 组合多条件,实现止盈止损等交易条件单
  3. 使用条件表达式(三元运算符)a if 条件 else b 简化简单的二选一赋值,并用嵌套 if 处理多层级决策
  4. 解释 Python 对象的真值规则(0、空字符串、空列表、None 为假),用 is/is not 正确判断 None

先修:章节 1(第1章 常用基本数据类型)、章节 2(第2章 列表、字典和元组)、章节 3(第3章 函数定义 算术平均收益率计算)、章节 4(第4章 常用内置函数)、章节 5(第5章 NumPy 数组的创建与访问)、章节 6(第6章 NumPy 数组运算)、章节 7(第7章 NumPy 矩阵处理)

8.3 If语句基础

理论背景:控制流(Control Flow)

从计算理论的角度来看,条件判断实现了程序的选择性执行(Selective Execution):

  • 根据条件的真值(True/False)选择执行不同代码块
  • 实现了图灵完备性的关键要素之一
  • 使得程序能够处理复杂的决策逻辑

正是这种”按条件选择执行路径”的能力,让下面的if语句能够表达真实的交易规则。

8.3.1 语法结构

Python的if语句使用缩进来组织代码块,这与其他使用花括号{}的语言不同。

列表 8.1: If条件语句的基本语法
# =============================================================================
# 题目:If条件语句的基本语法演示
# =============================================================================
# 本代码块展示了Python中if语句的三种基本结构:
# 1. 简单if语句 - 单分支条件判断
# 2. if-else结构 - 双分支条件判断
# 3. if-elif-else结构 - 多分支条件判断
# 这些结构是金融交易决策系统的基础,用于根据市场价格做出不同的操作决策

# ==================== 示例1:简单的if语句 ====================
price = 15.50  # 定义当前股票价格为15.50元

if price > 15.0:  # 判断价格是否高于15元
    print("价格高于15元")  # 如果条件为真,输出提示信息
    # 注意:缩进表示代码块 - Python使用4个空格缩进来表示代码块的层次
    print("考虑买入")  # 这是if语句块的第二个操作

# ==================== 示例2:if-else结构 ====================
if price > 20.0:  # 判断价格是否高于20元
    action = "卖出"  # 如果高于20元,建议卖出
else:  # 否则(价格不高于20元)
    action = "持有"  # 建议持有

print(f"建议操作: {action}")  # 输出最终的操作建议

# ==================== 示例3:if-elif-else结构(多重条件) ====================
if price > 20.0:  # 第一个条件:价格高于20元
    level = "高估"  # 给出估值水平
elif price > 15.0:  # 第二个条件:价格高于15元但不高于20元(elif=else if)
    level = "合理"  # 估值合理
elif price > 10.0:  # 第三个条件:价格高于10元但不高于15元
    level = "低估"  # 估值偏低
else:  # 最后的情况:价格不高于10元
    level = "严重低估"  # 估值严重偏低

print(f"估值水平: {level}")  # 输出估值判断结果

语法规则:

  1. 关键字: if, elif, else
  2. 条件表达式: 返回布尔值的表达式
  3. 冒号: 每个条件后必须有:
  4. 缩进: 统一使用4个空格
  5. elif: 可以有多个,else最多一个

8.3.2 比较运算符

Python提供了完整的比较运算符用于构建条件:

运算符 描述 示例 结果
== 等于 10 == 10 True
!= 不等于 10 != 5 True
< 小于 5 < 10 True
> 大于 10 > 5 True
<= 小于等于 5 <= 5 True
>= 大于等于 10 >= 10 True
列表 8.2: 比较运算符在金融条件判断中的应用
# =============================================================================
# 题目:比较运算符在交易决策中的应用
# =============================================================================
# 本代码演示如何在金融场景中使用比较运算符构建交易条件:
# - 使用>=判断是否达到止盈目标价
# - 使用<=判断是否触发止损
# - 结合多个比较运算符制定仓位管理策略
# 输出将展示基于当前价格的操作建议

# ==================== 定义交易参数 ====================
price = 18.50  # 当前股票价格
target_price = 20.00  # 目标止盈价格
stop_loss = 15.00  # 止损价格

# ==================== 基本比较:止盈判断 ====================
if price >= target_price:  # 判断当前价是否达到或超过目标价
    print("达到目标价,考虑止盈")  # 提示投资者考虑卖出获利

# ==================== 基本比较:止损判断 ====================
if price <= stop_loss:  # 判断当前价是否触及或跌破止损价
    print("触及止损位,必须平仓")  # 提示强制平仓以控制风险

# ==================== 多重条件:仓位管理 ====================
if price < stop_loss:  # 如果价格低于止损价
    position = "空仓"  # 建议空仓,避免进一步损失
elif price < target_price:  # 如果价格在止损价和目标价之间
    position = "持仓"  # 建议继续持有,等待价格回升
else:  # 如果价格高于或等于目标价
    position = "部分减仓"  # 建议卖出部分仓位锁定利润

print(f"当前建议: {position}")  # 输出最终的仓位管理建议
# 输出示例: "当前建议: 持仓" (因为18.50在15.00和20.00之间)

8.3.3 逻辑运算符

逻辑运算符用于组合多个条件:

运算符 描述 示例 含义
and 逻辑与 A and B A和B都为True
or 逻辑或 A or B A或B至少一个为True
not 逻辑非 not A A的否定

优先级: not > and > or

下例用到两个常用技术指标:RSI(相对强弱指标,衡量一段时间内涨跌动能的0-100指标,一般高于70视为超买、低于30视为超卖)与MA20(20日移动平均线,即最近20个交易日收盘价的平均值,用于判断中期趋势方向)。

列表 8.3: 逻辑运算符在复杂交易条件中的应用
# 注意:本代码块沿用上一代码块(lst-comparison-operators)中定义的stop_loss(止损价)变量

# =============================================================================
# 题目:使用逻辑运算符构建复合交易条件
# =============================================================================
# 本代码演示如何使用and、or、not逻辑运算符组合多个技术指标:
# - and运算符:所有条件同时满足时触发(严谨的交易信号)
# - or运算符:任一条件满足时触发(风险预警场景)
# - not运算符:对条件取反(排除特定情况)
# 这种多条件组合是量化交易策略的核心技术

# ==================== 定义市场数据 ====================
price = 18.50  # 当前股价
volume = 1500000  # 成交量(单位:手)
ma20 = 18.00  # 20日均线价格
rsi = 65  # RSI相对强弱指标(范围0-100)

# ==================== 复合条件1:价格突破且放量 ====================
if price > ma20 and volume > 1000000:  # 价格站上均线且成交量放大
    print("买入信号:放量突破均线")  # 这种技术形态被认为是强烈的看涨信号
    # and运算符确保两个条件必须同时为真,提高了信号的可靠性

# ==================== 复合条件2:超买或超卖预警 ====================
if rsi > 70 or rsi < 30:  # RSI超买(>70)或超卖(<30)
    print("警示:RSI进入极端区域")  # 提示市场可能即将反转
    # or运算符在任一条件满足时就触发,适合预警场景

# ==================== 复合条件3:严格的买入条件 ====================
# 价格在均线之上 AND RSI不超买 AND 成交量放大
buy_condition = (price > ma20) and (rsi < 70) and (volume > 1000000)
if buy_condition:  # 三个条件必须同时满足
    print("强烈买入信号")  # 这种多重确认的策略可以减少假信号

# ==================== 使用not运算符 ====================
if not (price < stop_loss):  # 等价于:price >= stop_loss
    print("未触发止损,继续持有")  # not运算符对条件取反
    # 在这个场景中,not使得代码逻辑更符合自然语言表达

补充说明:短路求值(Short-circuit Evaluation)

Python的andor运算符采用短路求值:

  • A and B: 如果A为False,不计算B(结果必为False)
  • A or B: 如果A为True,不计算B(结果必为True)

这在金融编程中非常重要,可以避免不必要的计算或错误:

列表 8.4: 短路求值在防止错误中的应用
# =============================================================================
# 题目:利用短路求值避免访问不存在的数据
# =============================================================================
# 本代码演示Python逻辑运算符的短路求值特性:
# - and运算符:第一个表达式为False时,第二个表达式不会被计算
# - or运算符:第一个表达式为True时,第二个表达式不会被计算
# 在金融数据处理中,这可以防止访问None对象或空数据引发的错误
# 这是防御性编程的重要技巧,在实际开发中经常使用

# ==================== 场景设置 ====================
data = None  # 数据可能缺失(模拟API返回数据为空的情况)

# ==================== 安全的检查:利用短路求值 ====================
if data is not None and data.price > 100:  # 先检查data不为None
    print("价格高于100")  # 只有data不为None时才会访问data.price
    # 短路求值机制:如果data is not None为False,
    # Python不会计算and后面的data.price > 100,
    # 从而避免AttributeError错误

# ==================== 危险的写法(会报错) ====================
# if data.price > 100 and data is not None:
#     print("价格高于100")
# 上面这行代码会导致错误: AttributeError: 'NoneType' object has no attribute 'price'
# 原因:当data为None时,Python会尝试计算data.price,立即报错
# 教训:必须先判断对象存在性,再访问其属性

8.4 实战案例制作交易条件单

8.4.1 止盈止损策略

任务要求:已知当前股价 price=14.88,止盈线 17 元、止损线 13 元,用 if/elif/else 判断并输出操作建议:股价达到或超过止盈线输出止盈卖出,跌破或等于止损线输出止损卖出,否则输出继续持有。请将代码原样输入教学平台(注释除外),判定以平台为准。

列表 8.5: 平台原始代码
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
price=14.88  # 设置当前股价为14.88元
if price>=17:  # 判断股价是否达到止盈线(17元)
  print("卖出股票,止盈")  # 股价达到止盈线,输出卖出建议
elif price<=13:  # 判断股价是否跌破止损线(13元)
  print("卖出股票,止损")  # 股价跌破止损线,输出止损建议
else:  # 股价在13-17元区间内
  print("继续持有")  # 股价处于合理区间,输出继续持有建议

预期输出(本机 Python 实际运行结果,具体以平台运行结果为准):

继续持有

判读要点:price=14.88 既不满足 price>=17,也不满足 price<=13,因此落入 else 分支;若把 price 改为 13.0,则会命中 elif price<=13 输出止损,可自行验证。

代码深度解析:

  1. if-elif-else的执行逻辑:
    • Python从上到下依次检查条件
    • 一旦某个条件为True,执行对应代码块后跳出
    • 最多只有一个分支被执行
  2. 策略的金融含义:
    • 止盈(Take Profit): 保护已实现的利润
    • 止损(Stop Loss): 限制潜在损失
    • 持有(Hold): 等待更好的价格
  3. 风险管理原则:
    • 止盈和止损应该事先设定
    • 止损比止盈更重要(保本为先)
    • 止损幅度通常小于止盈幅度(盈亏比>1)

8.4.2 多条件交易策略

列表 8.6: 基于多指标的复合交易策略
# =============================================================================
# 题目:多因子量化交易策略系统
# =============================================================================
# 本代码实现一个基于多个技术指标的复合交易策略:
# 1. 均线系统 - 判断趋势方向
# 2. 成交量分析 - 验证价格走势的可靠性
# 3. RSI指标 - 判断超买超卖状态
# 综合三个指标给出交易建议,提高决策的准确性
# 这种多因子模型是量化基金的常用方法,可以过滤假信号

# ==================== 导入数值计算库 ====================
import numpy as np  # 导入NumPy库用于数值计算

# ==================== 模拟市场数据 ====================
price = 28.50  # 当前股价
ma20 = 28.00  # 20日移动平均线(短期趋势)
ma60 = 27.50  # 60日移动平均线(长期趋势)
volume = 2500000  # 今日成交量(手)
avg_volume = 2000000  # 平均成交量(手)
rsi = 58  # RSI相对强弱指标(0-100范围)

# ==================== 交易策略:多因子模型 ====================
buy_signals = 0  # 买入信号计数器
sell_signals = 0  # 卖出信号计数器

# ==================== 条件1:均线系统分析 ====================
if ma20 > ma60:  # 判断短期均线是否在长期均线之上
    print("✓ 均线多头排列")  # 多头排列表示上升趋势
    buy_signals += 1  # 买入信号加1
else:  # 短期均线在长期均线之下
    print("✗ 均线空头排列")  # 空头排列表示下降趋势
    sell_signals += 1  # 卖出信号加1
# 均线系统是趋势跟踪的基础技术指标

# ==================== 条件2:成交量分析 ====================
if volume > avg_volume * 1.2:  # 成交量比平均值高20%
    print("✓ 放量上涨")  # 放量上涨表明资金流入,趋势可靠
    buy_signals += 1  # 买入信号加1
elif volume < avg_volume * 0.8:  # 成交量比平均值低20%
    print("✗ 缩量下跌")  # 缩量下跌表明市场缺乏承接
    sell_signals += 1  # 卖出信号加1
# 成交量是价格走势的验证指标,量价配合更可靠

# ==================== 条件3:RSI指标分析 ====================
if 40 <= rsi <= 60:  # RSI在40-60的中性区域
    print("✓ RSI处于中性区域")  # 中性区域适合建仓
    buy_signals += 1  # 买入信号加1
elif rsi > 70:  # RSI超过70,进入超买区
    print("✗ RSI超买")  # 超买可能预示回调
    sell_signals += 1  # 卖出信号加1
elif rsi < 30:  # RSI低于30,进入超卖区
    print("✗ RSI超卖")  # 超卖可能预示反弹
    buy_signals += 1  # 买入信号加1(超卖反而是买入机会)
# RSI用于判断市场的超买超卖状态,避免追涨杀跌

# ==================== 综合决策输出 ====================
print(f"\n买入信号数: {buy_signals}")  # 显示累计买入信号数量
print(f"卖出信号数: {sell_signals}")  # 显示累计卖出信号数量

# ==================== 最终交易建议 ====================
if buy_signals >= 2 and sell_signals == 0:  # 至少2个买入信号且无卖出信号
    print("\n建议: 建仓")  # 多个指标共振,强烈建议买入
elif sell_signals >= 2:  # 至少2个卖出信号
    print("\n建议: 平仓")  # 多个指标看空,建议清仓
else:  # 信号不明确或买卖信号混杂
    print("\n建议: 观望")  # 信号不明确,建议等待更好时机
# 这种多因子决策体系可以显著提高交易胜率

8.5 条件表达式(Ternary Operator)

Python支持简洁的条件表达式(三元运算符):

语法: value_if_true if condition else value_if_false

列表 8.7: 条件表达式的简洁写法
# =============================================================================
# 题目:条件表达式(三元运算符)的金融应用
# =============================================================================
# 本代码演示Python的条件表达式语法:
# - 传统if-else语句:适合多行代码块
# - 条件表达式:适合简单的单行赋值,代码更简洁
# 条件表达式在金融计算中广泛使用,特别是费率计算、状态判断等场景
# 掌握这个语法可以让代码更加Pythonic(符合Python风格)

# ==================== 定义变量 ====================
price = 18.50  # 当前股价

# ==================== 传统写法(if-else语句) ====================
if price > 20.0:  # 判断价格是否高于20元
    status = "高"  # 条件为真时赋值
else:  # 价格不高于20元
    status = "低"  # 条件为假时赋值
# 这种写法需要5行代码,逻辑分散

# ==================== 条件表达式(简洁写法) ====================
status = "高" if price > 20.0 else "低"  # 一行完成相同逻辑
# 语法结构: 值1 if 条件 else 值2
# 如果条件为True返回值1,否则返回值2

print(f"价格水平: {status}")  # 输出: "价格水平: 低"

# ==================== 嵌套条件表达式 ====================
level = "高" if price > 20 else ("中" if price > 15 else "低")
# 这个嵌套结构等价于:
# if price > 20:
#     level = "高"
# elif price > 15:
#     level = "中"
# else:
#     level = "低"

print(f"详细分级: {level}")  # 输出: "详细分级: 中"

# ==================== 金融应用:计算手续费 ====================
amount = 15000  # 交易金额(元)
# 根据交易金额选择不同的费率
commission_rate = 0.0003 if amount > 10000 else 0.0005
# 金额超过1万元,费率0.03%;否则费率0.05%

commission = amount * commission_rate  # 计算手续费
print(f"手续费: {commission:.2f}元")  # 输出: "手续费: 4.50元"
# 条件表达式使得费率选择逻辑清晰且在一行内完成

8.6 嵌套If语句

在复杂决策中,可能需要嵌套if语句:

列表 8.8: 嵌套if语句处理复杂决策逻辑
# =============================================================================
# 题目:嵌套条件语句实现分层交易决策
# =============================================================================
# 本代码演示如何使用嵌套if语句处理复杂的分层决策:
# 外层判断市场趋势,中层判断波动率,内层判断价格位置
# 这种分层决策结构模仿了人类交易员的思维过程
# 适合处理需要多个维度综合判断的金融决策场景

# ==================== 定义市场状态变量 ====================
price = 18.50  # 当前股价
market_trend = "up"  # 市场趋势: up(上涨), down(下跌), sideways(震荡)
volatility = "high"  # 波动率: low(低), medium(中), high(高)

# ==================== 外层:判断市场趋势 ====================
if market_trend == "up":  # 如果市场处于上涨趋势
    # ==================== 中层:判断波动率 ====================
    if volatility == "low":  # 低波动环境
        # ==================== 内层:判断价格位置 ====================
        if price > 20:  # 价格已经较高
            action = "谨慎追涨"  # 建议谨慎,避免高位接盘
        else:  # 价格适中
            action = "积极买入"  # 建议买入,趋势稳健
    elif volatility == "medium":  # 中等波动
        action = "分批建仓"  # 建议分批买入,控制风险
    else:  # 高波动(volatility == "high")
        action = "观望为主"  # 建议观望,等待市场稳定

elif market_trend == "down":  # 如果市场处于下跌趋势
    if volatility == "low":  # 低波动下跌
        action = "轻仓试探"  # 可以少量仓位试探
    else:  # 中高波动下跌
        action = "空仓观望"  # 建议空仓,避免损失

else:  # market_trend == "sideways",震荡市场
    action = "高抛低吸"  # 建议波段操作

# ==================== 输出决策报告 ====================
print(f"市场趋势: {market_trend}")  # 显示市场趋势
print(f"波动率: {volatility}")  # 显示波动率水平
print(f"当前价格: {price:.2f}元")  # 显示当前价格
print(f"建议操作: {action}")  # 显示最终决策
# 输出示例: "建议操作: 观望为主" (上涨趋势+高波动+价格18.50)

补充说明:控制复杂度

嵌套if语句虽然功能强大,但会降低代码可读性。当嵌套超过3层时,应考虑重构:

重构方法1: 使用提前返回(Early Return)

if volatility == "high" and market_trend != "up":
    return "观望为主"

if market_trend == "up":
    # 继续处理

重构方法2: 提取为独立函数

def check_uptrend_strategy(price, volatility):
    if volatility == "low":
        return "谨慎追涨" if price > 20 else "积极买入"
    # ...

8.7 真值测试(Truth Value Testing)

在if语句中,任何对象都可以进行布尔测试。

Falsy值(被视为False):

  • None, False
  • 数值0 (0, 0.0, 0j)
  • 空序列 ('', (), [], {})
  • 空集合 set()

Truthy值(被视为True):

  • 所有其他值
列表 8.9: 真值测试在数据验证中的应用
# =============================================================================
# 题目:真值测试在金融数据验证中的应用
# =============================================================================
# 本代码演示Python的真值测试机制:
# 在if语句中,任何对象都可以被隐式转换为布尔值
# 空容器、0、None等被视为False,非空和非零值被视为True
# 这种特性使得代码非常简洁,是Pythonic编程风格的重要体现
# 在金融数据处理中,常用于快速验证数据是否存在或有效

# ==================== 场景1:检查投资组合是否为空 ====================
portfolio = []  # 定义一个空的投资组合列表

if portfolio:  # 直接使用列表作为条件(等价于 len(portfolio) > 0)
    print("投资组合不为空")  # 列表非空时执行
else:  # 列表为空
    print("投资组合为空")  # 列表为空时执行
# 输出: "投资组合为空"
# 这种写法比 if len(portfolio) == 0: 更Pythonic

# ==================== 场景2:检查价格是否有效 ====================
price = 0  # 定义价格为0

if price:  # 数值0在布尔测试中为False
    print("有效价格")  # 非零价格时执行
else:  # 价格为0
    print("无效价格")  # 零价格时执行
# 输出: "无效价格"
# 在金融数据中,0可能表示数据缺失或停牌

# ==================== 场景3:检查股票代码是否存在 ====================
stock_code = ""  # 定义空字符串

if stock_code:  # 空字符串在布尔测试中为False
    print(f"股票代码: {stock_code}")  # 有代码时输出
else:  # 字符串为空
    print("股票代码缺失")  # 无代码时输出
# 输出: "股票代码缺失"
# 这种写法比 if stock_code == "": 更简洁

# ==================== 场景4:检查数据是否为None ====================
data = None  # 定义None对象(表示数据缺失)

if data is not None:  # 必须使用 is not None 来判断
    print("处理数据")  # 数据存在时执行
else:  # 数据为None
    print("数据缺失")  # 数据缺失时执行
# 输出: "数据缺失"
# 注意:判断None必须用 is 或 is not,不能用 == 或 !=
# 这是因为None是Python的单例对象,使用is判断更准确

8.8 本章小结

要点:

  • if/elif/else 自上而下求值,命中一个分支后其余分支不再判断
  • 比较运算符可以链式书写,如 13 <= price <= 17,等价于用 and 连接
  • and/or/not 组合多条件;三元表达式 a if 条件 else b 适合简单的二选一赋值
  • 0、0.0、''[]None 都是真值为假的对象;判断 None 用 is/is not

易错点:

  • 漏写冒号或缩进不一致,会触发 SyntaxError/IndentationError
  • = 是赋值、== 才是比较;浮点数直接用 == 比较可能因精度问题失真
  • if x == None 应写成 if x is None
  • 分支顺序不当会让本应触发止损或止盈的价格落入错误分支,条件范围要互斥且完备

8.9 动手与思考

以下练习每题附参考答案(默认折叠)。请先独立完成并写下你的判断,再点开对照,最后上机验证。

  1. 输出预测:不运行代码,先写出下面代码的输出结果,再上机检验你的判断。

    price = 13.0
    if price >= 17:
        print("止盈")
    elif price <= 13:
        print("止损")
    else:
        print("持有")
    print("A" if 13 < 14.88 < 17 else "B")
    data = [0.0, 5.2]
    if data[0]:
        print("非零")
    else:
        print("零值")

    参考答案(先写下你的预测再点开)

    解题思路:逐段推演。第一段:price = 13.0,先判 price >= 17 为假,再判 price <= 13,13.0 恰好等于 13,条件成立(<= 含端点),输出 止损,命中分支后 else 不再执行。第二段:13 < 14.88 < 17 是链式比较,等价于 13 < 14.88 and 14.88 < 17,两者皆真,三元表达式取 "A",输出 A。第三段:data[0]0.0,数值零在真值测试中为假,if data[0]:else 分支,输出 零值

    # 验证脚本:依次验证分支选择、链式比较与真值测试
    price = 13.0  # 当前股价恰好等于止损线
    if price >= 17:  # 止盈条件:13.0不满足
        print('止盈')
    elif price <= 13:  # 止损条件:13.0小于等于13成立(含端点)
        print('止损')
    else:  # 前两个分支都未命中才执行
        print('持有')
    print('A' if 13 < 14.88 < 17 else 'B')  # 链式比较为真,取A
    data = [0.0, 5.2]  # data[0]为数值0.0
    if data[0]:  # 0.0真值为假
        print('非零')
    else:
        print('零值')  # 走else分支

    预期输出(本机 peter 环境实际运行结果,具体以平台运行结果为准):

    止损
    A
    零值

    回扣本章:对应本章小结“要点”第 1、2、4 条——分支自上而下求值且 <= 含端点、链式比较等价于 and 连接、数值 0 为假值。

  2. 概念辨析:==is 的区别是什么,判断 None 为什么必须用后者?13 <= price <= 17price >= 13 and price <= 17 是否完全等价?再说明:0、0.0、空列表的 True/False 判定规则,以及把 if data[0]: 误写成 if data[0] is True:data[0] = 0.0data[0] = 5.2 两种取值的输出差异。

    参考答案(点开前请先独立完成)

    解题思路:逐点作答。第一,== 比较两个对象的是否相等,is 比较两个名字是否指向同一个对象(同一内存地址)。判断 None 必须用 is None,因为 None 是解释器中的单例对象,is 判断的是身份、语义明确且不会被重载,而 == 可能被自定义类重载出意外行为,PEP 8 也明确要求用 is/is not 判 None(对 None 两种写法结果一致,但只有 is 是规范写法)。第二,13 <= price <= 17price >= 13 and price <= 17 完全等价:Python 把链式比较展开为后者(且 price 只求值一次),本机实测两者同为 True。第三,真值判定规则:00.0 数值为零即假,空列表 [] 长度为零即假,其余非零数值与非空容器为真。第四,误写 if data[0] is True: 后行为改变:is True 只在对象恰好是布尔单例 True 时成立,0.05.2 都是 float、不是 True,因此两种取值都会走 else 分支(本机实测 0.05.2 均输出“非 True 分支”);而原写法 if data[0]: 依赖真值测试,0.0 为假走 else5.2 为真走 if 分支——用 is True 会把“非零即真”的真值判断变成“必须是布尔 True”,5.2 这类合法的浮点条件值会被误判。

    # 验证脚本:==/is、链式比较等价性与 is True 误写的差异
    none_value = None  # 定义None值
    print(none_value is None, none_value == None)  # 身份判断与值比较
    price = 14.88  # 当前股价
    print(13 <= price <= 17, price >= 13 and price <= 17)  # 两种写法完全等价
    print(bool(0), bool(0.0), bool([]))  # 数值零与空列表均为假值
    for value in [0.0, 5.2]:  # 分别检验两种写法
        if value is True:  # 误写:只匹配布尔单例True
            print('is True 分支')
        else:
            print('is False 分支', value)
        if value:  # 正写:真值测试
            print('真值分支', value)
        else:
            print('假值分支', value)

    预期输出(本机 peter 环境实际运行结果,具体以平台运行结果为准):

    True True
    True True
    False False False
    is False 分支 0.0
    假值分支 0.0
    is False 分支 5.2
    真值分支 5.2

    回扣本章:对应本章小结“要点”第 2、4 条与“易错点”第 3 条——链式比较等价于 and 连接、0 与空容器为假值、判 None 须用 is

  3. 变式任务(平台任务同型改造):把止盈止损策略改造成三档条件单——price >= 17 输出”卖出股票,止盈”,price <= 13 输出”卖出股票,止损”,13 < price < 15 输出”股价偏低,关注补仓机会”,其余输出”继续持有”。分别用 price = 17.5price = 16.5price = 14.2price = 12.8 四个取值运行四次,确认止盈、持有、偏低、止损每档都能正确触发。

    参考答案(点开前请先独立完成)

    解题思路:分支顺序很关键。先判 price >= 17(止盈),再判 price <= 13(止损),此时剩下的价格都满足 13 < price < 17,第三档只需再判 price < 15 即可锁定 13 < price < 15(偏低档),最后的 else 自然就是 15 <= price < 17(持有档)——四个分支互斥且完备。四个测试价逐一对照:17.5 命中第一档输出止盈;16.5 前两档不中、也不小于 15,落入 else 输出继续持有;14.2 前两档不中且 14.2 < 15,输出股价偏低;12.8 命中第二档输出止损。

    # 变式程序:三档条件单的四档触发验证
    for price in [17.5, 16.5, 14.2, 12.8]:  # 依次测试四个档位的代表价格
        if price >= 17:  # 止盈档:达到或超过止盈线
            print(price, '卖出股票,止盈')
        elif price <= 13:  # 止损档:跌破或等于止损线
            print(price, '卖出股票,止损')
        elif price < 15:  # 偏低档:此时必满足13<price<15
            print(price, '股价偏低,关注补仓机会')
        else:  # 持有档:剩余区间15<=price<17
            print(price, '继续持有')

    预期输出(本机 peter 环境实际运行结果,具体以平台运行结果为准):

    17.5 卖出股票,止盈
    16.5 继续持有
    14.2 股价偏低,关注补仓机会
    12.8 卖出股票,止损

    注意:以上为本题变式的独立代码;列表 8.5 对应平台任务的原始代码块仍须原样输入教学平台,不要用本变式替换。

    回扣本章:对应本章小结“易错点”第 4 条——条件范围要互斥且完备,分支顺序不当会让价格落入错误分支。

  4. 动手验证:用嵌套 if 实现”价量共振”判断:当 price >= 17volume_ratio >= 2(量比)时输出”放量突破,卖出止盈”,当 price >= 17 但量比不足时输出”缩量新高,暂持有”,其余情况输出”继续观察”;再用三元表达式改写第一层判断并对比两种写法的可读性。

    参考答案(点开前请先独立完成)

    解题思路:嵌套写法的外层先判断价格是否达到止盈线,内层再判断量比是否放大到 2 倍:外层成立且量比足,输出“放量突破,卖出止盈”;外层成立但量比不足,输出“缩量新高,暂持有”;外层不成立则直接输出“继续观察”,内层不再执行。三元改写把第一层(价格档)折进条件表达式:外层条件为 price >= 17,为真时再由内层三元式在两个输出中选择,为假时取“继续观察”。可读性对比:嵌套 if 每层一行条件、结构像决策树,易于逐层添加日志或语句;三元式把整个二乘二决策压成一行,适合简单赋值,层次一多就难读——本例两层尚可,超过两层建议保留嵌套写法。

    # 验证脚本:嵌套if与三元表达式两种写法对照
    price = 17.60  # 当前股价已达到止盈线
    volume_ratio = 2.3  # 量比(成交量为均值的倍数)
    if price >= 17:  # 第一层:价格达到止盈线
        if volume_ratio >= 2:  # 第二层:量比是否放大
            print('放量突破,卖出止盈')
        else:
            print('缩量新高,暂持有')
    else:  # 价格未达止盈线
        print('继续观察')
    action = ('放量突破,卖出止盈' if volume_ratio >= 2 else '缩量新高,暂持有') if price >= 17 else '继续观察'  # 三元式改写
    print(action)  # 输出与嵌套写法一致

    预期输出(本机 peter 环境实际运行结果,具体以平台运行结果为准):

    放量突破,卖出止盈
    放量突破,卖出止盈

    回扣本章:对应本章小结“要点”第 3 条——嵌套 if 处理多层级决策,三元表达式 a if 条件 else b 适合简单的二选一赋值。